import os
import json
import requests
import logging

# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class LLMService:
    """
    一个专门用于与阿里云通义千问大模型API交互的服务类。
    它封装了API请求的细节，如构建请求头、处理请求体和解析响应。
    """

    def __init__(self, model_name: str = "qwen-max"):
        """
        初始化LLM服务。

        最佳实践是从环境变量中读取API密钥，以避免将其硬编码在代码中。
        """
        self.api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
        
        # 优先从环境变量获取API Key，如果不存在，则使用你在代码中提供的key作为后备
        self.api_key = os.getenv('DASHSCOPE_API_KEY')
        if not self.api_key:
            self.api_key = "sk-f6c68712c4f44b01a57c758e7fa18be5" # 这是你在代码中提供的后备Key
            logging.warning("未找到环境变量 'DASHSCOPE_API_KEY'，正在使用代码中硬编码的后备API Key。")

        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }
        
        # 将模型参数也作为类的一部分，方便统一管理
        self.model_name = model_name
        self.model_parameters = {
            "temperature": 0.1,
            "top_p": 0.8,
            "max_length": 1500  # 稍微增加长度以适应更复杂的输出
        }

    def invoke(self, prompt: str) -> str:
        """
        使用给定的提示词调用大模型，并返回纯文本结果。

        :param prompt: 发送给大模型的完整提示词。
        :return: 大模型返回的纯文本字符串，如果出错则返回错误信息。
        """
        if not self.api_key:
            error_msg = "API密钥未配置，无法调用LLM服务。"
            logging.error(error_msg)
            return error_msg

        # 构建符合通义千问API要求的请求体
        data = {
            "model": self.model_name,
            "input": {
                "prompt": prompt
            },
            "parameters": self.model_parameters
        }

        try:
            # 发起POST请求
            response = requests.post(self.api_url, headers=self.headers, data=json.dumps(data))
            
            # 检查HTTP状态码，如果不是2xx，则抛出异常
            response.raise_for_status()
            
            # 解析JSON响应
            result = response.json()
            
            # 从嵌套结构中安全地提取文本输出
            text_output = result.get("output", {}).get("text", "")
            
            if not text_output:
                logging.warning(f"LLM返回了成功状态码，但响应中没有文本输出。完整响应: {result}")
                return "模型返回了空内容。"

            return text_output.strip()

        except requests.exceptions.HTTPError as http_err:
            # 处理HTTP错误（如401, 404, 500等）
            error_msg = f"HTTP错误发生: {http_err} - 响应内容: {response.text}"
            logging.error(error_msg)
            return error_msg
        except requests.exceptions.RequestException as req_err:
            # 处理网络相关的错误（如连接超时）
            error_msg = f"网络请求错误发生: {req_err}"
            logging.error(error_msg)
            return error_msg
        except json.JSONDecodeError:
            # 处理无法解析为JSON的响应
            error_msg = f"无法解析LLM返回的JSON响应。响应内容: {response.text}"
            logging.error(error_msg)
            return error_msg
        except Exception as e:
            # 捕获其他所有未知错误
            error_msg = f"调用LLM服务时发生未知错误: {e}"
            logging.error(error_msg)
            return error_msg